package com.kexio.auth.dto;

import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Set;

import com.fasterxml.jackson.annotation.JsonInclude;

/**
 * 登录响应DTO
 * 
 * 用户登录成功后返回的响应数据，包含token、用户信息和权限信息
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
@JsonInclude(JsonInclude.Include.NON_NULL)
public class LoginResponse implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    /**
     * 访问令牌
     */
    private String accessToken;
    
    /**
     * 刷新令牌
     */
    private String refreshToken;
    
    /**
     * 令牌类型（固定为Bearer）
     */
    private String tokenType = "Bearer";
    
    /**
     * 访问令牌过期时间（秒）
     */
    private Long expiresIn;
    
    /**
     * 刷新令牌过期时间（秒）
     */
    private Long refreshExpiresIn;
    
    /**
     * 用户基本信息
     */
    private UserInfo userInfo;
    
    /**
     * 用户权限信息
     */
    private AuthInfo authInfo;
    
    /**
     * 登录时间
     */
    private LocalDateTime loginTime;
    
    /**
     * 登录IP
     */
    private String loginIp;
    
    /**
     * 会话ID
     */
    private String sessionId;
    
    /**
     * 权限版本（用于前端本地缓存一致性）
     */
    private Long permVersion;
    
    // ==================== 内部类：用户基本信息 ====================
    
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class UserInfo implements Serializable {
        private String userId;
        private String tenantId;
        private String username;
        private String nickname;
        private String email;
        private String phone;
        private String avatar;
        private String deptId;
        private String deptName;
        private Integer status;
        
        // 构造函数
        public UserInfo() {}
        
        public UserInfo(String userId, String username, String nickname) {
            this.userId = userId;
            this.username = username;
            this.nickname = nickname;
        }
        
        // Getter/Setter
        public String getUserId() { return userId; }
        public void setUserId(String userId) { this.userId = userId; }
        public String getTenantId() { return tenantId; }
        public void setTenantId(String tenantId) { this.tenantId = tenantId; }
        public String getUsername() { return username; }
        public void setUsername(String username) { this.username = username; }
        public String getNickname() { return nickname; }
        public void setNickname(String nickname) { this.nickname = nickname; }
        public String getEmail() { return email; }
        public void setEmail(String email) { this.email = email; }
        public String getPhone() { return phone; }
        public void setPhone(String phone) { this.phone = phone; }
        public String getAvatar() { return avatar; }
        public void setAvatar(String avatar) { this.avatar = avatar; }
        public String getDeptId() { return deptId; }
        public void setDeptId(String deptId) { this.deptId = deptId; }
        public String getDeptName() { return deptName; }
        public void setDeptName(String deptName) { this.deptName = deptName; }
        public Integer getStatus() { return status; }
        public void setStatus(Integer status) { this.status = status; }
    }
    
    // ==================== 内部类：权限信息 ====================
    
    @JsonInclude(JsonInclude.Include.NON_NULL)
    public static class AuthInfo implements Serializable {
        private List<RoleInfo> roles;
        private Set<String> permissions;
        private List<MenuInfo> menus;
        private DataScopeInfo dataScope;
        
        // 构造函数
        public AuthInfo() {}
        
        public AuthInfo(List<RoleInfo> roles, Set<String> permissions) {
            this.roles = roles;
            this.permissions = permissions;
        }
        
        // Getter/Setter
        public List<RoleInfo> getRoles() { return roles; }
        public void setRoles(List<RoleInfo> roles) { this.roles = roles; }
        public Set<String> getPermissions() { return permissions; }
        public void setPermissions(Set<String> permissions) { this.permissions = permissions; }
        public List<MenuInfo> getMenus() { return menus; }
        public void setMenus(List<MenuInfo> menus) { this.menus = menus; }
        public DataScopeInfo getDataScope() { return dataScope; }
        public void setDataScope(DataScopeInfo dataScope) { this.dataScope = dataScope; }
    }
    
    // ==================== 构造函数 ====================
    
    public LoginResponse() {}
    
    public LoginResponse(String accessToken, String refreshToken) {
        this.accessToken = accessToken;
        this.refreshToken = refreshToken;
    }
    
    public LoginResponse(String accessToken, String refreshToken, Long expiresIn) {
        this(accessToken, refreshToken);
        this.expiresIn = expiresIn;
    }
    
    // ==================== 便捷方法 ====================
    
    /**
     * 判断是否有刷新令牌
     */
    public boolean hasRefreshToken() {
        return refreshToken != null && !refreshToken.trim().isEmpty();
    }
    
    /**
     * 判断访问令牌是否即将过期（30分钟内）
     */
    public boolean willExpireSoon() {
        if (expiresIn == null) return false;
        return expiresIn <= 1800; // 30分钟 = 1800秒
    }
    
    /**
     * 设置用户基本信息的便捷方法
     */
    public LoginResponse withUserInfo(String userId, String username, String nickname) {
        this.userInfo = new UserInfo(userId, username, nickname);
        return this;
    }
    
    /**
     * 设置权限信息的便捷方法
     */
    public LoginResponse withAuthInfo(List<RoleInfo> roles, Set<String> permissions) {
        this.authInfo = new AuthInfo(roles, permissions);
        return this;
    }
    
    // ==================== Getter/Setter ====================
    
    public String getAccessToken() {
        return accessToken;
    }
    
    public void setAccessToken(String accessToken) {
        this.accessToken = accessToken;
    }
    
    public String getRefreshToken() {
        return refreshToken;
    }
    
    public void setRefreshToken(String refreshToken) {
        this.refreshToken = refreshToken;
    }
    
    public String getTokenType() {
        return tokenType;
    }
    
    public void setTokenType(String tokenType) {
        this.tokenType = tokenType;
    }
    
    public Long getExpiresIn() {
        return expiresIn;
    }
    
    public void setExpiresIn(Long expiresIn) {
        this.expiresIn = expiresIn;
    }
    
    public Long getRefreshExpiresIn() {
        return refreshExpiresIn;
    }
    
    public void setRefreshExpiresIn(Long refreshExpiresIn) {
        this.refreshExpiresIn = refreshExpiresIn;
    }
    
    public UserInfo getUserInfo() {
        return userInfo;
    }
    
    public void setUserInfo(UserInfo userInfo) {
        this.userInfo = userInfo;
    }
    
    public AuthInfo getAuthInfo() {
        return authInfo;
    }
    
    public void setAuthInfo(AuthInfo authInfo) {
        this.authInfo = authInfo;
    }
    
    public LocalDateTime getLoginTime() {
        return loginTime;
    }
    
    public void setLoginTime(LocalDateTime loginTime) {
        this.loginTime = loginTime;
    }
    
    public String getLoginIp() {
        return loginIp;
    }
    
    public void setLoginIp(String loginIp) {
        this.loginIp = loginIp;
    }
    
    public String getSessionId() {
        return sessionId;
    }
    
    public void setSessionId(String sessionId) {
        this.sessionId = sessionId;
    }
    
    public Long getPermVersion() { return permVersion; }
    public void setPermVersion(Long permVersion) { this.permVersion = permVersion; }
    
    @Override
    public String toString() {
        return "LoginResponse{" +
                "accessToken='[PROTECTED]'" +
                ", refreshToken='[PROTECTED]'" +
                ", tokenType='" + tokenType + '\'' +
                ", expiresIn=" + expiresIn +
                ", refreshExpiresIn=" + refreshExpiresIn +
                ", userInfo=" + userInfo +
                ", authInfo=" + authInfo +
                ", loginTime=" + loginTime +
                ", loginIp='" + loginIp + '\'' +
                ", sessionId='" + sessionId + '\'' +
                '}';
    }
}
